<template>
  <div class="upload-att-container">
    <a-upload-dragger
      :multiple="true"
      :show-upload-list="false"
      :before-upload="beforeUpload"
      :customRequest="customRequest"
      :transformFile="transformFile"
      :accept="accept"
    >
      <div class="upload-att-wrapper" @click="checkSecret">
        <span class="upload-att">{{ $i18n('common.upload.attachment.label') }}</span>
        <span>({{ fileLength }})</span>
        <span v-if="showMaxSize" class="upload-max-size">
          ({{ $i18n('collaboration.common.fileUpload.maxSize', uploadMaxSize) }})
        </span>
      </div>
    </a-upload-dragger>
    <a-tooltip :title="$i18n('collaboration.pageDesigner.update.atta.tip')">
      <icon-font type="cap-icon-weibiaoti6-copy" class="tip-icon color-primary" />
    </a-tooltip>
  </div>
</template>

<script>
  import api from '@/api';
  import {
    checkSecret,
    checkFileStatus,
    deleteUploadingAttachment,
    addUploadingAttachment
  } from './helper';
  import UploadFile from './upload';
  import { useBaseInfoWithOut } from '@/store/modules/base-info';

  //默认最大可上传大小(M)
  const DEFAULT_MAX_SIZE = 2048;
  //同一时刻的随机字符串。拿来断点续传用
  const breakpointId = `${Date.now()}${Math.random()}`;

  export default {
    name: 'UploadAtt',
    props: {
      //气泡弹出窗位置
      placement: {
        type: String,
        default: 'topRight'
      },
      //正在上传或者已上传的文件
      fileList: {
        type: Array,
        default: () => []
      },
      //最大可上传多少M
      maxSize: {
        type: Number,
        default: DEFAULT_MAX_SIZE
      },
      //是否需要选择密级
      //如果要启用，要确定isSecretLevelEnable为true
      isSetSecretLevel: {
        type: Boolean,
        default: false
      },
      //最大上传个数
      uploadMaxNumber: {
        type: Number,
        default: Infinity
      },
      //限制上传文件类型
      //适配三种场景：image/png、.png、image/*
      //https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept
      accept: {
        type: String,
        default: ''
      },
      request: {
        type: Object,
        default: () => ({
          upload: api.uploadFileUpload,
          getState: api.uploadGetFileState
        })
      },
      showMaxSize: {
        //是否显示最大上传限制
        type: Boolean,
        default: false
      }
    },
    data() {
      return {
        uploadFileList: [],
      };
    },
    beforeDestroy() {
      //销毁之前，有正在上传的就，取消上传
      this.uploadFileList.forEach((file) => {
        if (file.skelecton.isUploading) {
          file.skelecton.cancel();
        }
      });
    },
    computed: {
      uploadMaxSize() {
        return this.maxSize || this.maxSize === 0 ? Number(this.maxSize) : DEFAULT_MAX_SIZE;
      },
      fileLength() {
        return this.fileList.filter(item => !item.from||item.from === 'uploadAtta').length;
      },
    },
    methods: {
      checkSecret(event) {
        if (!useBaseInfoWithOut().checkSecret()) {
          event.stopPropagation();
        }
      },
      /**
       * @description: 上传之前做的操作
       * @param {File}file 选择的文件
       * @param {Array<File>}fileList 选择的文件列表
       */
      beforeUpload(file, fileList) {
        console.log('file:', file.isChecked);
        console.log(this.$error);
        //选多个会执行多次。让他只执行一次,一次验证。
        if (file.isChecked) return false;
        //校验过后，文件标识为已校验
        fileList.forEach((f) => (f.isChecked = true));
        //保存上传文件
        this.uploadFileList = fileList;
        //只有第一个文件进行验证。后面的文件直接拿结果
        // let allList = fileList;
        //如果有已上传或者正在上传的，也要加进列表,某些判断需要
        // if (this.fileList?.length) {
        //     allList = fileList.concat(this.fileList);
        // }
        //检查数量是否超标
        // if (this.uploadMaxNumber < allList.length) {
        //     this.$message.error(this.$i18n(`最多只能上传${this.uploadMaxNumber}个文件`, this.uploadMaxNumber));
        //     return false;
        // }
        //检查大小。所有文件总大小
        // if (
        //     allList.reduce((p, n) => (p.size ? +p.size : p) + (n.size ? +n.size : n), 0) /
        //         1024 /
        //         1024 >
        //     this.uploadMaxSize
        // ) {
        //     this.$message.error(this.$i18n(`附件总大小不能超过${this.uploadMaxSize}M`, this.uploadMaxSize));
        //     return false;
        // }
        //检查文件类型
        if (this.accept) {
          //如果有一个不能匹配到允许的类型也不行
          //适配三种场景：image/png、.png、image/*
          //只要有一个文件在三种场景中一种都不满足，就不继续了
          const acceptArray = this.accept.split(',');
          if (
            fileList.some(
              (f) =>
                !acceptArray.some(
                  (accept) =>
                    accept === f.type ||
                    accept === /\.\w+$/.exec(f.name)[0] ||
                    accept.slice(0, -2) === f.type.split('/')[0]
                )
            )
          ) {
            this.$message.error(
              this.$i18n('fileupload.exception.UnallowedExtension.settings', this.accept)
            );
            return false;
          }
        }
        //文件大小检查
        console.log(fileList);
        let totalSize = fileList
          .map((item) => item.size)
          .reduce((acc, fileSize) => acc + Number(fileSize), 0);
        console.log('文件总体大小', totalSize);
        console.log('最大', Number(this.uploadMaxSize) * 1024 * 1024);
        if (this.uploadMaxSize && Number(this.uploadMaxSize) * 1024 * 1024 < totalSize) {
          this.$error({
            content: this.$i18n('fileupload.exception.MaxSize', this.uploadMaxSize + 'M')
          });

          return false;
        }
        //上传之前检查密级。然后检查状态
        const checks = async () => {
          await checkSecret(fileList, this.isSetSecretLevel);
          await checkFileStatus(this.request.getState, breakpointId, fileList);
        };
        return checks();
      },
      /**
       * @description: 上传之前转换文件
       * @param {*}file
       * @return {*}
       */
      transformFile(file) {
        console.log('transformFile', file);
        return file;
      },
      /**
       * @description:自定义上传。暂时就直接上传
       */
      async customRequest() {
        //上传文件
        this.uploadFileList.forEach((file) => {
          //创建上传中对象占位
          const skelecton = {
            fileUrl: file.uid,
            filename: file.name,
            isUploading: true,
            size: file.size,
            iconFont: 'defaultICON', //默认图标，上传完毕再修改
            process: 0,
            from: 'uploadAtta',
          };
          //文件里面也保存下以便摧毁之前取消上传
          file.skelecton = skelecton;

          const uploader = new UploadFile({
            file,
            request: this.request,
            breakpointId,
            process: (process) => {
              process = process !== 100 ? process : 99.9;
              console.log(process);

              skelecton.process = process;
            },
            fail: (isCancel) => {
              if (isCancel) {
                this.$message.error({
                  content: () => (
                    <span>
                      {this.$i18n('pdf.activex.menu_125')} <b class="color-danger">{file.name}</b>
                      {this.$i18n('collaboration.common.cancel.upload')}
                    </span>
                  )
                });
              }

              //上传失败，删除临时文件
              deleteUploadingAttachment(this.fileList, skelecton.fileUrl);
            },
            finish: (att) => {
              att.process = 100;
              //上传成功，改成真实数据onUploadProgress
              Reflect.deleteProperty(skelecton, 'isUploading');
              //正式把文件加进去
              Object.assign(skelecton, att);
              //以下事件发送以后有必要再添加
              // this.$emit('uploadSuccess', att);
            }
          });
          //上传开始
          uploader.uploadStart(file);
          //添加取消上传方法
          skelecton.cancel = uploader.stopUpload.bind(uploader);
          //把临时占位对象添加到列表
          addUploadingAttachment(this.fileList, skelecton);
        });
      }
    }
  };
</script>
<style lang="scss" scoped>
  .upload-att-container {
    display: flex;
    align-items: center;

    .upload-att-wrapper {
      display: flex;
      align-items: center;
      color: $c9;

      > .upload-att {
        color: #1890ff;
        color: var(--theme-brand6,#1890ff);
        &:hover {
          color: #40a9ff;
          color: var(--theme-brand4, #40a9ff);
        }
      }

      > .upload-max-size {
        margin-left: 4px;
      }
    }

    > .tip-icon {
      font-size: 14px;
      margin-left: 5px;
    }
  }
</style>
<style lang="scss">
  .upload-att-container {
    .ant-upload.ant-upload-drag {
      background-color: transparent;
      border: 0;

      .ant-upload {
        padding: 0;
      }
    }
  }
</style>
